﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using YanZhiwei.DotNet2.Utilities.Base;
namespace YanZhiwei.DotNet2.Utilities.Common
{
    /// <summary>
    /// 序列化帮助类
    /// <para>tooltip:</para>
    /// <para>[XmlAttribute("id")]==><XmlDocRoot id="1" /></para>
    /// <para>[XmlIgnore()]</para>
    /// <para>[XmlArrayItem("ListItem", typeof(string))]</para>
    /// <para>[XmlArray("List")]</para>
    /// </summary>
    public static class SerializeHelper
    {
        #region 将集合序列化成xml
        /// <summary>
        /// 将集合序列化成xml
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="savePath">保存路径</param>
        /// <param name="collection">数据</param>
        public static void ToXML<T>(string savePath, IList<T> collection)
        {
            using (Stream _stream = new FileStream(savePath, FileMode.Create, FileAccess.Write))
            {
                XmlTextWriter _xmlTextWriter = new XmlTextWriter(_stream, new UTF8Encoding(false));
                _xmlTextWriter.Formatting = Formatting.Indented;
                XmlSerializer _xmlSerializer = new XmlSerializer(collection.GetType());
                _xmlSerializer.Serialize(_xmlTextWriter, collection);
                _xmlTextWriter.Flush();
                _xmlTextWriter.Close();
            }
        }
        #endregion
        #region 将xml反序列化
        /// <summary>
        /// 将xml反序列化
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="path">xml路径</param>
        /// <returns>IList<T></returns>
        public static IList<T> XMLToCollection<T>(string path)
        {
            using (Stream _stream = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                XmlSerializer _xmlSerializer = new XmlSerializer(typeof(List<T>));
                return (IList<T>)_xmlSerializer.Deserialize(_stream);
            }
        }
        #endregion
        #region 将xml反序列化为实体类型
        /// <summary>
        /// 将xml反序列化为实体类型
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="path">xml路径</param>
        /// <returns>实体</returns>
        public static T XMLToObject<T>(string path) where T : class
        {
            using (Stream _stream = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                XmlSerializer _xmlSerializer = new XmlSerializer(typeof(T));
                return (T)_xmlSerializer.Deserialize(_stream);
            }
        }
        #endregion
        #region binay文件反序列化
        /// <summary>
        /// binay文件反序列化
        /// </summary>
        /// <typeparam name="T">反序列化类型</typeparam>
        /// <param name="path">xml路径</param>
        /// <returns>IList<T></returns>
        public static IList<T> BinaryToCollection<T>(string path)
        {
            IFormatter _serFormatter = new BinaryFormatter();
            _serFormatter.Binder = new UBinder();
            using (Stream _stream = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                return (IList<T>)_serFormatter.Deserialize(_stream);
            }
        }
        #endregion
        #region 将Binary文件反序列化成datatable
        /// <summary>
        /// 将Binary文件反序列化成datatable
        /// </summary>
        /// <param name="path">Binary文件路径</param>
        /// <returns>DataTable</returns>
        public static DataTable BinaryToDataTable(string path)
        {
            IFormatter _serFormatter = new BinaryFormatter();
            _serFormatter.Binder = new UBinder();
            using (Stream _stream = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                return (DataTable)_serFormatter.Deserialize(_stream);
            }
        }
        #endregion
        #region 将实体类序列化成xml
        /// <summary>
        /// 将实体类序列化成xml
        /// </summary>
        /// <typeparam name="T">实体类</typeparam>
        /// <param name="savePath">xml保存路径</param>
        /// <param name="t">实体类型</param>
        public static void ToXML<T>(string savePath, T t)
        {
            using (Stream _stream = new FileStream(savePath, FileMode.Create, FileAccess.Write))
            {
                XmlTextWriter _xmlTextWriter = new XmlTextWriter(_stream, new UTF8Encoding(false));
                _xmlTextWriter.Formatting = Formatting.Indented;
                XmlSerializer _xmlSerializer = new XmlSerializer(t.GetType());
                _xmlSerializer.Serialize(_xmlTextWriter, t);
                _xmlTextWriter.Flush();
                _xmlTextWriter.Close();
            }
        }
        #endregion
        #region 将实体类集合序列化成Binary文件
        /// <summary>
        /// 将实体类集合序列化成Binary文件
        /// </summary>
        /// <typeparam name="T">实体类类型</typeparam>
        /// <param name="savePath">保存路径</param>
        /// <param name="collection">IList</param>
        public static void ToBinary<T>(string savePath, IList<T> collection)
        {
            IFormatter _serFormatter = new BinaryFormatter();
            using (Stream _stream = new FileStream(savePath, FileMode.Create, FileAccess.Write))
            {
                _serFormatter.Serialize(_stream, collection);
            }
        }
        #endregion
        #region 将datatable序列化Binary文件
        /// <summary>
        /// 将datatable序列化Binary文件
        /// </summary>
        /// <param name="savePath">Binary文件保存论据</param>
        /// <param name="datatable">需要被序列化的datatable</param>
        public static void ToBinary(string savePath, DataTable datatable)
        {
            IFormatter _serFormatter = new BinaryFormatter();
            using (Stream _stream = new FileStream(savePath, FileMode.Create, FileAccess.Write))
            {
                _serFormatter.Serialize(_stream, datatable);
            }
        }
        #endregion
        #region 将xml文件读取
        /// <summary>
        /// 将xml文件转换string类型
        /// </summary>
        /// <param name="path">路径</param>
        /// <returns>string</returns>
        public static string XMLToString(string path)
        {
            XmlDocument _xmlDoc = new XmlDocument();
            _xmlDoc.Load(path);
            StringBuilder _xmlBuilder = new StringBuilder();
            StringWriter _xmlSw = new StringWriter(_xmlBuilder);
            XmlTextWriter _xmlWriter = new XmlTextWriter(_xmlSw);
            _xmlWriter.Formatting = Formatting.Indented;
            _xmlDoc.WriteContentTo(_xmlWriter);
            return _xmlBuilder.ToString();
        }
        #endregion
        #region 将对象序列化成字符串
        /// <summary>
        /// 将对象序列化成字符串
        /// </summary>
        /// <param name="obj">object</param>
        /// <returns>string</returns>
        public static string SerializeString(this object obj)
        {
            if (null == obj)
                return string.Empty;
            Type _type = obj.GetType();
            FieldInfo[] _fields = _type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
            StringBuilder _objString = new StringBuilder();
            foreach (FieldInfo field in _fields)
            {
                object _value = field.GetValue(obj);
                _objString.Append(field.Name + ":" + _value + ";");
            }
            return _objString.ToString();
        }
        #endregion 
        #region 二进制序列化

        /// <summary>
        /// 将数据序列化为二进制数组
        /// </summary>
        public static byte[] ToBinary(object data)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(ms, data);
                ms.Seek(0, 0);
                return ms.ToArray();
            }
        }

        /// <summary>
        /// 将二进制数组反序列化为强类型数据
        /// </summary>
        public static T FromBinary<T>(byte[] bytes)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();
                return (T)formatter.Deserialize(ms);
            }
        }

        /// <summary>
        /// 将数据序列化为二进制数组并写入文件中
        /// </summary>
        public static void ToBinaryFile(object data, string fileName)
        {
            using (FileStream fs = new FileStream(fileName, FileMode.Create))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(fs, data);
            }
        }

        /// <summary>
        /// 将指定二进制数据文件还原为强类型数据
        /// </summary>
        public static T FromBinaryFile<T>(string fileName)
        {
            using (FileStream fs = new FileStream(fileName, FileMode.Open))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                return (T)formatter.Deserialize(fs);
            }
        }

        #endregion

        #region XML序列化

        /// <summary>
        /// 将数据序列化为XML形式
        /// </summary>
        public static string ToXml(object data)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                XmlSerializer serializer = new XmlSerializer(data.GetType());
                serializer.Serialize(ms, data);
                ms.Seek(0, 0);
                return Encoding.Default.GetString(ms.ToArray());
            }
        }

        /// <summary>
        /// 将XML数据反序列化为强类型
        /// </summary>
        public static T FromXml<T>(string xml)
        {
            byte[] bytes = Encoding.Default.GetBytes(xml);
            using (MemoryStream ms = new MemoryStream())
            {
                XmlSerializer serializer = new XmlSerializer(typeof(T));
                return (T)serializer.Deserialize(ms);
            }
        }

        /// <summary>
        /// 将数据序列化为XML并写入文件
        /// </summary>
        public static void ToXmlFile(object data, string fileName)
        {
            using (FileStream fs = new FileStream(fileName, FileMode.Create))
            {
                XmlSerializer serializer = new XmlSerializer(data.GetType());
                serializer.Serialize(fs, data);
            }
        }

        /// <summary>
        /// 将指定XML数据文件还原为强类型数据
        /// </summary>
        public static T FromXmlFile<T>(string fileName)
        {
            using (FileStream fs = new FileStream(fileName, FileMode.Open))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(T));
                return (T)serializer.Deserialize(fs);
            }
        }

        #endregion
    }
}